package com.woniuxy.third.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniuxy.third.annotation.RequirePermission;
import com.woniuxy.third.controller.UserController;
import com.woniuxy.third.entity.Goods;
import com.woniuxy.third.entity.Perms;
import com.woniuxy.third.entity.Role;
import com.woniuxy.third.entity.User;
import com.woniuxy.third.enums.ResponseEnum;
import com.woniuxy.third.enums.TokenEnum;
import com.woniuxy.third.result.ResponseResult;
import com.woniuxy.third.service.RoleService;
import com.woniuxy.third.service.UserService;
import com.woniuxy.third.utils.GetUserUtil;
import com.woniuxy.third.utils.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.List;

/**
 * @Author: yangtao
 * @date 2021/7/14 14:28
 * @Version 1.0
 */
@Component  //加入IOC容器
public class PermsInterceptor extends HandlerInterceptorAdapter {
    //日志
    private static final Logger logger= LoggerFactory.getLogger(PermsInterceptor.class);
    @Resource
    private UserService userService;

    @Resource
    private RoleService roleService;

    //在handerler方法执行之前执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        ResponseResult<List<Goods>> responseResult = new ResponseResult<>();
        response.setContentType("application/json,charset=utf-8");

        logger.debug("拦截请求");
        //得到token
        String token = request.getHeader("authorization");

        //1.得到即将被访问的方法
        //如果请求的是handler中的方法
        if (handler instanceof HandlerMethod){
            logger.debug("获取请求的方法");
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            logger.debug("判断方法上是否有指定注解");
            if (method.isAnnotationPresent(RequirePermission.class)){
                //判断token是否为空
                if (token == null) {
                    logger.debug("没有登录");
                    responseResult.setCode(500).setMessage("你没有登录");
                    responseResult.setStatus(ResponseEnum.NO_LOGIN);
                    String json = new ObjectMapper().writeValueAsString(responseResult);
                    response.getWriter().write(json);
                    return false;
                }
                //校验token：有可能伪造，过期
                if (JwtUtil.verify(token) == TokenEnum.TOKEN_FAIL){
                    logger.debug("token非法");
                    responseResult.setCode(500).setMessage("非法token");
                    responseResult.setStatus(ResponseEnum.TOKEN_ERROR);
                    String json = new ObjectMapper().writeValueAsString(responseResult);
                    response.getWriter().write(json);
                    return false;
                }
                //
                if (JwtUtil.verify(token) == TokenEnum.TOKEN_EXPIRE){
                    logger.debug("token过期，重新生成");
                    //重新生成token
                    token  = JwtUtil.generateToken(JwtUtil.getAccount(token));
                    //更新前台的token
                    //将token放到响应头
                    response.setHeader("authorization",token);
                    //将响应头暴露给第三方
                    response.setHeader("Access-Control-Expose-Headers","authorization");
                    return true;
                }
                logger.debug("方法上有注解，得到注解对象");
                RequirePermission rp = method.getDeclaredAnnotation(RequirePermission.class);
                logger.debug("获取注解中的值");
                String perms = rp.value();
                logger.debug("value ="+perms);

                //通过当前用户的账号，查询出他所有的权限进行对比
                //调用service查询数据库数据
                User user = GetUserUtil.getUser(request);
                List<Role> rolesByUid = roleService.findRolesByUid(user.getId());
                user.setRoles(rolesByUid);
                for (Role role : rolesByUid) {
                  for (Perms perm : role.getPerms()) {
                    if (perm.getPname().equals(perms)){
                        logger.debug("有权限，放行");
                        return true;
                    }
                  }
                }
                logger.debug("没有权限操作，拒绝请求");

                responseResult.setCode(500).setMessage("你没有权限");
                String json = new ObjectMapper().writeValueAsString(responseResult);
                response.getWriter().write(json);
                return false;
            }

        }

        return super.preHandle(request, response, handler);
    }
}






















